package com.gxaedu.shiro.realm;

import com.gxaedu.shiro.pojo.Auth;
import com.gxaedu.shiro.pojo.Role;
import com.gxaedu.shiro.pojo.User;
import com.gxaedu.shiro.service.UserService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.realm.SimpleAccountRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component("myRealm2")
public class MyRealm extends AuthorizingRealm {


    @Autowired
    private UserService userService;

    /**
     * 授权的方法:  看用户是否有对应的权限, 这个地方我们要查询出用户所拥有的权限列表
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
       /* // 先获取用户名
        String  userName = (String) principalCollection.getPrimaryPrincipal();
        // 获取用户所有的信息
        User user = getAllUserByUserName(userName);
        // 获取角色信息, 权限信息
        List<String> roles = getRoles(user);
        List<String> auths = getAuths(user);
        // 返回授权信息: 角色和权限
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        // 添加角色数据
        simpleAuthorizationInfo.addRoles(roles);
        // 添加权限数据
        simpleAuthorizationInfo.addStringPermissions(auths);
        return simpleAuthorizationInfo;*/
       String userName = (String)principalCollection.getPrimaryPrincipal();
       User user = getAllUserByUserName(userName);
       List<String> roles = getRoles(user);
       List<String> auths = getAuths(user);
       SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
       simpleAuthorizationInfo.addRoles(roles);
       simpleAuthorizationInfo.addStringPermissions(auths);
       return simpleAuthorizationInfo;

    }

    /**
     * 获取String的auth
     * @param user
     * @return
     */
    private List<String> getAuths(User user) {
        List<String> stringAuth = new ArrayList<>();
        // 先获取角色
        List<Role> roles = user.getRoles();
        // 遍历角色
        for (Role role : roles) {
            List<Auth> auths = role.getAuths();
            for (Auth auth : auths) {
                // 空的权限不能加进去
                if (auth.getAuthUrl() == null || auth.getAuthUrl().isEmpty()) {
                    continue;
                }
                stringAuth.add(auth.getAuthUrl());
            }
        }
        return stringAuth;
    }

    /**
     * 获取String 的 roles
     * @param user
     * @return
     */
    private List<String> getRoles(User user) {
        List<String> stringRoles = new ArrayList<>();
        List<Role> roles = user.getRoles();
        for (Role role : roles) {
            // 添加角色的名字
            stringRoles.add(role.getRoleName());
        }
        return stringRoles;
    }

    /**
     * 查询用户的所有信息
     * @param userName
     * @return
     */
    private User getAllUserByUserName(String userName) {
        return userService.findAllUser(userName);
    }

    /**
     * 认证: 用户登陆
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        /*// 通过token去获取用户名
        String userName = (String) authenticationToken.getPrincipal();
        // 通过用户名去查询密码
        String password =  getPwdByUserName(userName);
        // 判断密码
        if(password == null){
            return null;
        }
        // 返回认证信息
        return new SimpleAuthenticationInfo(userName,password,"myRealm");*/
        String userName = (String)authenticationToken.getPrincipal();
        String password = getPwdByUserName(userName);
        if(password == null){
            return null;
        }
        // 返回认证信息
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(userName, password, "myRealm");
        // 设置加盐字符串
        info.setCredentialsSalt(ByteSource.Util.bytes("java211"));
        return info;
    }

    /**
     * 通过用户名去查询密码
     * @param userName
     * @return
     */
    private String getPwdByUserName(String userName) {
        // 通过userService 查询用户对象
        //User dbUser = userService.findSimpleUser(userName);
        //需要权限和角色信息的数据，所以换另一个方法
        User dbUser = userService.findAllUser(userName);
        // 判断
        if(dbUser == null){
            return null;
        }
        // 存储到redis中
        userService.saveUserToRedis(dbUser);
        return dbUser.getUserPassword();
    }
}
